package cn.xeblog.server.action.specialAc;

import cn.hutool.core.lang.Singleton;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.xeblog.commons.entity.IpRegion;
import cn.xeblog.commons.entity.User;
import cn.xeblog.commons.entity.UserMsgDTO;
import cn.xeblog.commons.enums.MessageType;
import cn.xeblog.commons.enums.specialAc.CountEnum;
import cn.xeblog.commons.util.ChatGPTUtil;
import cn.xeblog.server.action.ChannelAction;
import cn.xeblog.server.builder.ResponseBuilder;
import cn.xeblog.server.cache.BlackUserCache;
import cn.xeblog.server.cache.UserCache;
import cn.xeblog.server.config.ServerConfig;
import cn.xeblog.server.util.BaiDuFyUtil;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 功能描述:
 * <p>
 * Copyright © 2023 金卡水务科技有限公司. All rights reserved.
 *
 * @author ZhangLei
 * @date 2023/5/9 13:33
 */
@Slf4j
public class SpecialCommandHandler {

    private final static String flag = ":::";

    /**
     * @return 是否发所有人
     */
    public static boolean customSendMessage(User user, UserMsgDTO body, String msg) {
        String[] split = msg.split(flag);
        String command = split[0];
        boolean isRandomAdmin = user == UserCache.adminUser;
        List<String> excluded = ServerConfig.getConfig().getExcluded();
        if (excluded.contains(command)) {
            user.send(ResponseBuilder.system("该指令已被禁用！请联系塘主。"));
            return false;
        }

        List<String> adminList = ServerConfig.getConfig().getAdminList();
        if (adminList.contains(command) && (!user.isAdmin() && !isRandomAdmin)) {
            user.send(ResponseBuilder.system("您不是管理员，无权操作！"));
            return false;
        }

        AcEnum acEnum = AcEnum.getByKey(command);
        return acEnum == null || acEnum.doAction(user, body, split);
    }

    public static void blackControl(User user, UserMsgDTO body, String[] split, String control) {
        // 发给自己
        user.send(ResponseBuilder.build(user, body, MessageType.USER));

        int index = checkIndex(user, split[1]);

        if ("add".equals(control)) {
            BlackUserCache.addBlackList(index, split[2]);
            user.send(ResponseBuilder.system(split[2] + "已列入黑名单！"));
        } else if ("remove".equals(control)) {
            BlackUserCache.removeBlackList(index, split[2]);
            user.send(ResponseBuilder.system(split[2] + "已移出黑名单！"));
        } else if ("clear".equals(control)) {
            BlackUserCache.clearBlackList(index);
            user.send(ResponseBuilder.system("清空黑名单列表[" + index + "]"));
        }
    }

    public static void blackControlAdd(User user) {
        String username = user.getUsername();
        String uuid = user.getUuid();
        String ip = user.getIp();

        if (StrUtil.isNotBlank(username)) {
            BlackUserCache.addBlackList(1, username);
        }
        if (StrUtil.isNotBlank(ip)) {
            BlackUserCache.addBlackList(2, ip);
        }
        if (StrUtil.isNotBlank(uuid)) {
            BlackUserCache.addBlackList(3, uuid);
        }
    }

    public static void blackControlRemove(User user) {
        String username = user.getUsername();
        String uuid = user.getUuid();
        String ip = user.getIp();

        if (StrUtil.isNotBlank(username)) {
            BlackUserCache.removeBlackList(1, username);
        }
        if (StrUtil.isNotBlank(ip)) {
            BlackUserCache.removeBlackList(2, ip);
        }
        if (StrUtil.isNotBlank(uuid)) {
            BlackUserCache.removeBlackList(3, uuid);
        }
    }

    public static int checkIndex(User user, String indexStr) {
        int index = -1;
        try {
            index = Integer.parseInt(indexStr.trim());
        } catch (Exception e) {
            log.info("index解析异常！", e);
            user.send(ResponseBuilder.system("index解析异常！请检查！"));
        }
        return index;
    }

    public static void showBlackList(User user, UserMsgDTO body, String[] split) {
        // 发给自己
        user.send(ResponseBuilder.build(user, body, MessageType.USER));

        int index = checkIndex(user, split[1]);
        if (index == 0) {
            user.send(ResponseBuilder.system("黑名单列表[" + 1 + "]：" + BlackUserCache.getBlackList(1)));
            user.send(ResponseBuilder.system("黑名单列表[" + 2 + "]：" + BlackUserCache.getBlackList(2)));
            user.send(ResponseBuilder.system("黑名单列表[" + 3 + "]：" + BlackUserCache.getBlackList(3)));
        } else {
            user.send(ResponseBuilder.system("黑名单列表[" + index + "]：" + BlackUserCache.getBlackList(index)));
        }
    }

    /**
     * 统计在线用户
     *
     * @author G009468 ZhangLei
     * @date 2023/8/30 11:30
     */
    public static void countOnlineUsers(User user, UserMsgDTO body, String[] split) {

        boolean toAll = false;
        boolean isDetail = false;
        int showSize = 6;

        switch (split.length) {
            case 3:
                toAll = "all".equals(split[2]);
                break;
            case 4:
                toAll = "all".equals(split[2]);
                isDetail = "detail".equals(split[3]);
                break;
            case 5:
                toAll = "all".equals(split[2]);
                isDetail = "detail".equals(split[3]);
                showSize = NumberUtil.isNumber(split[4]) ? NumberUtil.parseInt(split[4]) : showSize;
                break;
        }

        // 发给自己
        if (toAll) {
            ChannelAction.send(user, body, MessageType.USER);
        } else {
            user.send(ResponseBuilder.build(user, body, MessageType.USER));
        }

        int index = checkIndex(user, split[1]);
        CountEnum countEnum = CountEnum.getByIndex(index);
        if (countEnum == null) {
            user.send(ResponseBuilder.system("index有误！"));
            return;
        }

        List<User> users = UserCache.listUser();
        String consoleTableStr = isDetail ? CountOnlineUserUtil.showAllUsers(users, countEnum, showSize)
                : CountOnlineUserUtil.getConsoleTableStr(users, countEnum);

        // 表格消息
        String dateMsg = StrUtil.format("现在时间是:{}\n{}", dateFormat.format(new Date()), consoleTableStr);
        if (toAll) {
            ChannelAction.send(ResponseBuilder.system(dateMsg));
        } else {
            user.send(ResponseBuilder.system(dateMsg));
        }
    }

    public static void translate(User user, UserMsgDTO body, String[] split) {
        String translate = Singleton.get(BaiDuFyUtil.class.getName(), () -> new BaiDuFyUtil("", "")).translate(split[1]);
        body.setContent(String.join(flag, split[0], translate));
        ChannelAction.send(user, body, MessageType.USER);
    }

    public static void talkToAI(User user, UserMsgDTO body, String[] split) {
        String type = split[1];
        String msg = split[2];

        body.setContent(String.join(flag, split));
        switch (type) {
            case "ALL":
                ChannelAction.send(user, body, MessageType.USER);
                ChannelAction.send(ResponseBuilder.system(ChatGPTUtil.getText(msg)));
                break;
            case "SELF":
                // 发给自己
                user.send(ResponseBuilder.build(user, body, MessageType.USER));
                user.send(ResponseBuilder.system(ChatGPTUtil.getText(msg)));
                break;
            default:
                break;
        }
    }

    public static void talkToUser(User user, UserMsgDTO body, String[] split) {
        String toUserName = split[1];
        String msg = split[2];

        // 原封不动发给自己
        user.send(ResponseBuilder.build(user, body, MessageType.USER));
        if (user.getUsername().equals(toUserName)) {
            user.send(ResponseBuilder.system("发给自己？是不是很无聊？"));
            return;
        }

        User toUser = UserCache.getUserByUsername(toUserName);
        // 发给对方
        if (toUser != null) {
            UserMsgDTO msgDTO = new UserMsgDTO(StrUtil.format("私聊消息 :: {}", msg), new String[]{toUserName});
            toUser.send(ResponseBuilder.build(user, msgDTO, MessageType.USER));
        } else {
            user.send(ResponseBuilder.system(StrUtil.format("用户[{}]不存在！", toUserName)));
        }
    }

    public static String getTips(boolean isAdmin) {
        List<String> excluded = ServerConfig.getConfig().getExcluded();
        List<String> adminList = ServerConfig.getConfig().getAdminList();

        AcEnum[] acEnums = AcEnum.values();
        StringBuilder builder = new StringBuilder("欢迎使用鼓励师鱼塘！目前【服务端】支持以下特殊指令，【客户端】指令请输入“#”查看。").append("\n");
        int index = 1;
        for (AcEnum acEnum : acEnums) {
            if (excluded.contains(acEnum.getKey()))
                continue;
            if (!isAdmin && adminList.contains(acEnum.getKey()))
                continue;
            builder.append(index++).append("、").append(acEnum.getDesc()).append("\n");
        }
        return builder.toString();
    }

    public static String countDown() {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime expireTime = LocalDateTime.parse("2099-12-31 23:59:59", timeFormatter);
        if (now.isAfter(expireTime)) {
            return "";
        }

        Duration duration = Duration.between(now, expireTime);
        // 手动构建时间差的表示
        long days = duration.toDays();
        long hours = duration.minusDays(days).toHours();
        long minutes = duration.minusDays(days).minusHours(hours).toMinutes();
        return StrUtil.format("温馨提示：此鱼塘还剩{}天{}小时{}分钟的生命，请各位鱼友耗子尾汁。\n", days, hours, minutes);
    }

    static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    static final Timer timer = new Timer();

    public static void startTimerTask() {

        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                Date now = new Date();
                Calendar instance = Calendar.getInstance();
                instance.setTime(now);
                int hour = instance.get(Calendar.HOUR_OF_DAY);
                if (hour >= 7 && hour <= 22) {
                    String consoleTableStr = CountOnlineUserUtil.getConsoleTableStr(UserCache.listUser(), CountEnum.PROVINCE);
                    String countDown = countDown();
                    String dateMsg = StrUtil.format("现在时间是:{}\n{}\n{}\n当前鱼塘服务器由 爱吃炸鸡的桔梗 和 气球舞王 倾情赞助！", dateFormat.format(now), consoleTableStr, countDown);
                    ChannelAction.send(ResponseBuilder.system(dateMsg));
                    User user = UserCache.randomAdminUser();
                    if (user != null) {
                        String adminChangeStr = StrUtil.format("恭喜塘友 {} 被随机为本小时的管理员！！！ 无人扶我青云志，我自踏雪至山巅", user.getUsername());
                        ChannelAction.send(ResponseBuilder.system(adminChangeStr));
                    }
                    ChannelAction.sendUpgradeMsg();
                }
            }
        };
        Date firstTime = getNextHour();                // 设置定时器第1次执行的开始时间
        long period = TimeUnit.HOURS.toMillis(1);    // 设置每隔1小时执行1次
        timer.scheduleAtFixedRate(task, firstTime, period);
    }

    public static void randomAdminToken() {
        String randomToken = RandomUtil.randomString(RandomUtil.BASE_CHAR, 16);
        ServerConfig.getConfig().setToken(randomToken);
        log.info("随机管理员token：{}", randomToken);
    }
    /**
     * 获取当前时间的下一个小时的整点时间
     */
    public static Date getNextHour() {
        Calendar calendar = Calendar.getInstance();
        log.info("==> 计时器：当前时间 = " + dateFormat.format(calendar.getTime()));

        calendar.set(Calendar.MILLISECOND, 0);  // 清空毫秒
        calendar.set(Calendar.SECOND, 0);       // 清空秒
        calendar.set(Calendar.MINUTE, 0);       // 清空分
        calendar.add(Calendar.HOUR, 1);     // 添加1小时

//        calendar.add(Calendar.MINUTE, 1);     // 添加1分钟 用预测试

        Date nextHour = calendar.getTime();
        log.info("==> 计时器：开始时间 = " + dateFormat.format(nextHour));
        return nextHour;
    }

    public static void oilPrice(User user, UserMsgDTO body, String[] splits) {
        ChannelAction.send(user, body, MessageType.USER);
        String province = "";
        IpRegion region = user.getRegion();
        if (region != null) {
            province = StrUtil.replace(region.getProvince(), "省", "");
        }
        if (splits.length >= 2) {
            province = splits[1];
        }
        // 表格消息
        String search = OilSearchUtil.oilSearch(province);
        String dateMsg = StrUtil.format("现在时间是:{}\n{}", dateFormat.format(new Date()), search);
        ChannelAction.send(ResponseBuilder.system(dateMsg));
    }
}
